﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Chemistry.Models;
using Chemistry.Tools;
using GalaSoft.MvvmLight.Command;

namespace Chemistry.ViewModels
{
    public class ConfigExaminationPointViewModel:VmBase
    {
        private int _min_index;
        private int _max_index;
        private Workflow _currentFlow;

        private ObservableCollection<PropertyNodeItem> nodes;
        public ObservableCollection<PropertyNodeItem> NodeList
        {
            get { return nodes; }
            set { nodes = value; RaisePropertyChanged("NodeList"); }
        }
        private ObservableCollection<ExaminationPoint> _points;
        public ObservableCollection<ExaminationPoint> Points
        {
            get { return _points; }
            set { _points = value; RaisePropertyChanged("Points"); }
        }

        private ExaminationPoint _selectpoint;
        public ExaminationPoint SelectedPoint
        {
            get { return _selectpoint; }
            set { _selectpoint = value; RaisePropertyChanged("SelectedPoint"); }
        }

        public RelayCommand UpCommand { get; set; }
        public RelayCommand DownCommand { get; set; }
        public RelayCommand DeleteCommand { get; set; }
        public ConfigExaminationPointViewModel()
        {
            InitFlows();
            UpCommand = new RelayCommand(UpExec,()=>SelectedPoint!=null&&SelectedPoint.Index>_min_index);
            DownCommand = new RelayCommand(DownExec,()=>SelectedPoint!=null&& SelectedPoint.Index<_max_index);
            DeleteCommand = new RelayCommand(DeleteExec,()=>SelectedPoint!=null);
            CommitCommand = new RelayCommand(CommitExec,()=>Points!=null&&Points.Count>0);
            InitMessage();
        }

        #region 命令方法
        private async void DeleteExec()
        {
            if (SelectedPoint.Id == 0)
            {
                Points.Remove(SelectedPoint);
            }
            else
            {
                try
                {
                    string request_url = string.Format("{0}/DeletePoint?pointid={1}", workflow_url, SelectedPoint.Id);
                    var result = await HttpBaseChemistry.GetAsync<ChemistryApiReuslt>(request_url);
                    if (result.status == 0)
                    {
                        Points.Remove(SelectedPoint);
                    }
                    else if (result.status == -3)
                    {
                        ShowMessage("服务器内部错误，请联系管理员");
                    }
                }
                catch (Exception ex)
                {
                    AppendExecptionAsync(ex);
                    ShowMessage("错误：" + ex.Message);
                }
            }
        }

        private async void CommitExec()
        {
            int index = 0;
            foreach (var item in Points)
            {
                index++;
                if (item.Id == 0)
                {
                    item.WorkFlowId = _currentFlow.Id;
                }
                item.Index = index;

                if (item.Operator == Operator.区间)
                {                    
                    var min = Math.Min(item.Value1, item.Value2);
                    var max = Math.Max(item.Value1, item.Value2);
                    item.Value1 = min;
                    item.Value2 = max;
                }
            }
            string request_url = string.Format("{0}/ModifyPoint", workflow_url);
            try
            {
                var result = await HttpBaseChemistry.PostAsJsonAsync<ChemistryApiReuslt>(request_url, Points);
                if (result.status == 0)
                {
                    int flowid = _currentFlow.Id;
                    await FreshPoint(flowid);
                }
                else if (result.status == -3)
                {
                    ShowMessage("服务器内部错误，请联系管理员");
                }                
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
                ShowMessage(ex.Message);
            }
        }

        private void DownExec()
        {
            int nextIndex = SelectedPoint.Index + 1;
            Points.SingleOrDefault(i => i.Index == nextIndex).Index--;
            SelectedPoint.Index++;
            var r = Points.OrderBy(i => i.Index);
            Points = new ObservableCollection<ExaminationPoint>(r);
        }
        private void UpExec()
        {
            int preIndex = SelectedPoint.Index - 1;
            Points.SingleOrDefault(i => i.Index == preIndex).Index++;
            SelectedPoint.Index--;
            var r = Points.OrderBy(i => i.Index);
            Points = new ObservableCollection<ExaminationPoint>(r);
        }

        #endregion

        private void InitMessage()
        {
            Register<PropertyNodeItem>(this, MessageToken.SelectFlowForPoint, async (i) =>
            {
                _currentFlow = i.Tag as Workflow;
                await FreshPoint(_currentFlow.Id);
            });
        }

        private async Task FreshPoint(int p)
        {
            var points =await GetPointsByFlowId(p);
            if (points != null&& points.Count>0)
            {
                this.Points = new ObservableCollection<ExaminationPoint>(points);
                _min_index = Points.Min(i => i.Index);
                _max_index = Points.Max(i => i.Index);
            }
            else
            {
                this.Points = new ObservableCollection<ExaminationPoint>();
            }
        }

        

        private async void InitFlows()
        {
            string request_url = string.Format("{0}/GetWorkflow", workflow_url);
            var workflowapi_result = await HttpBaseChemistry.GetAsync<WorkflowApiModel>(request_url);
            if (workflowapi_result != null && workflowapi_result.status == 0)
            {
                NodeList = new ObservableCollection<PropertyNodeItem>();
                var flows = workflowapi_result.Workflows;
                foreach (var item in flows)
                {
                    PropertyNodeItem pitem = new PropertyNodeItem()
                    {
                        Name = item.Name,
                        Tag = item
                    };
                    NodeList.Add(pitem);
                }
            }

        }


        private async Task<List<ExaminationPoint>> GetPointsByFlowId(int flowid)
        {
            List<ExaminationPoint> points = null;
            try
            {
                string request_url = string.Format("{0}/GetPointsByFlowId?flowId={1}", workflow_url, flowid);
                var result = await HttpBaseChemistry.GetAsync<ExamPointApiModel>(request_url);
                if (result != null && result.status == 0)
                {
                    points = result.points;
                }
            }
            catch (Exception ex)
            {
                AppendExecptionAsync(ex);
            }
            return points;
        }
    }
}
